export class HtmlUtil {
  /**
   * 转义HTML特殊字符
   * @param html 需要转义的HTML字符串
   * @returns 转义后的字符串
   */
  public static escape(html: string): string {
    const el = document.createElement('div');
    el.innerText = html;
    return el.innerHTML;
  }

  /**
   * 反转义HTML实体
   * @param text 包含HTML实体的文本
   * @returns 反转义后的HTML
   */
  public static unescape(text: string): string {
    const el = document.createElement('div');
    el.innerHTML = text;
    return el.innerText;
  }

  /**
   * 从HTML字符串中提取纯文本
   * @param html HTML字符串
   * @returns 纯文本内容
   */
  public static stripTags(html: string): string {
    return html.replace(/<\/?[^>]+(>|$)/g, '');
  }

  /**
   * 从HTML中提取所有链接
   * @param html HTML字符串
   * @returns 链接URL数组
   */
  public static extractLinks(html: string): string[] {
    const links: string[] = [];
    const regex = /href=["']([^"']+)["']/g;
    let match;
    
    while ((match = regex.exec(html)) !== null) {
      links.push(match[1]);
    }
    
    return links;
  }

  /**
   * 从HTML中提取所有图片链接
   * @param html HTML字符串
   * @returns 图片URL数组
   */
  public static extractImages(html: string): string[] {
    const images: string[] = [];
    const regex = /src=["']([^"']+)["']/g;
    let match;
    
    while ((match = regex.exec(html)) !== null) {
      if (html.slice(match.index - 4, match.index).toLowerCase() === '<img') {
        images.push(match[1]);
      }
    }
    
    return images;
  }

  /**
   * 将HTML字符串解析为DOM元素
   * @param html HTML字符串
   * @returns DOM元素
   */
  public static parseHTML(html: string): HTMLElement {
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');
    return doc.body;
  }

  /**
   * 创建安全的HTML标记（用于防止XSS攻击）
   * @param tagName 标签名
   * @param attributes 属性对象
   * @param content 标签内容
   * @returns 安全的HTML字符串
   */
  public static createSafeTag(tagName: string, attributes: Record<string, string> = {}, content: string = ''): string {
    // 白名单标签
    const safeTagNames = [
      'div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
      'ul', 'ol', 'li', 'a', 'img', 'table', 'tr', 'td', 'th', 'tbody', 'thead',
      'strong', 'em', 'code', 'pre', 'blockquote'
    ];
    
    // 白名单属性
    const safeAttributes = [
      'id', 'class', 'href', 'src', 'alt', 'title', 'style',
      'width', 'height', 'target', 'rel'
    ];
    
    // 检查标签名是否在白名单中
    if (!safeTagNames.includes(tagName.toLowerCase())) {
      return this.escape(content);
    }
    
    // 过滤属性
    const safeAttributesObj: Record<string, string> = {};
    for (const [key, value] of Object.entries(attributes)) {
      if (safeAttributes.includes(key.toLowerCase())) {
        // 对属性值进行清理
        safeAttributesObj[key] = value.replace(/["'<>]/g, '');
      }
    }
    
    // 构建HTML标签
    const attributesStr = Object.entries(safeAttributesObj)
      .map(([key, value]) => `${key}="${value}"`)
      .join(' ');
    
    const attrString = attributesStr ? ` ${attributesStr}` : '';
    
    // 自闭合标签
    if (tagName.toLowerCase() === 'img') {
      return `<${tagName}${attrString} />`;
    }
    
    return `<${tagName}${attrString}>${content}</${tagName}>`;
  }

  /**
   * 创建自定义样式的HTML表格
   * @param headers 表头数组
   * @param rows 数据行数组
   * @param className 表格CSS类名
   * @returns HTML表格字符串
   */
  public static createTable(
    headers: string[],
    rows: any[][],
    className: string = 'html-table'
  ): string {
    let tableHtml = `<table class="${className}">`;
    
    // 表头
    tableHtml += '<thead><tr>';
    for (const header of headers) {
      tableHtml += `<th>${this.escape(header)}</th>`;
    }
    tableHtml += '</tr></thead>';
    
    // 表内容
    tableHtml += '<tbody>';
    for (const row of rows) {
      tableHtml += '<tr>';
      for (const cell of row) {
        tableHtml += `<td>${this.escape(String(cell))}</td>`;
      }
      tableHtml += '</tr>';
    }
    tableHtml += '</tbody>';
    
    tableHtml += '</table>';
    return tableHtml;
  }

  /**
   * 高亮HTML中的代码块
   * @param html HTML字符串
   * @param highlightClass 高亮CSS类名
   * @returns 高亮后的HTML
   */
  public static highlightCode(html: string, highlightClass: string = 'code-highlight'): string {
    return html.replace(
      /<pre><code>([\s\S]*?)<\/code><\/pre>/g,
      `<pre><code class="${highlightClass}">$1</code></pre>`
    );
  }
}
